Passed
Push — master ( ad9a28...55041a )
by Night
56s
created

arrayFuncs.moveDown   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 2
nop 1
dl 0
loc 16
rs 10
c 0
b 0
f 0
1
/** global: UB */
2
/** global: Buffer */
3
4
/*! ARRAY UTILS */
5
6
var arrayFuncs = {
7
8
	merge: function(){
9
		var arr = this;
10
		var val1 = arr[0];
11
12
		// if array of strings
13
		if (val1.isString()){
14
			return val1.join("");
15
		}
16
17
		// if array of arrays
18
		if (val1.isArray()){
19
			var merged = [];
20
			for (var a = 0, al = arr.length; a<al; a++){
21
				merged.addArray(arr[a]);
22
			}
23
			return merged;
24
		}
25
26
		// if array of Buffers
27
		//removeIf(nodejs)
28
		if (val1 instanceof Buffer){
29
30
			// calc the total length of all buffers
31
			var buffers = arr;
32
			var len = 0;
33
			for(var b = 0, bl = buffers.length; b < bl; b++) {
34
				len += buffers[b].length;
35
			}
36
37
			// create a new buffer of that length
38
			var mega = new Buffer(len);
39
40
			// write all buffers into the mega buffer
41
			var cur = 0;
42
			for(var b = 0, bl = buffers.length; b < bl; b++) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable bl already seems to be declared on line 33. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable b already seems to be declared on line 33. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
43
				buffers[b].copy(mega, cur, 0);
44
				cur += buffers[b].length;
45
			}
46
			return mega;
47
		}
48
		//endRemoveIf(nodejs)
49
50
		return null;
51
	},
52
	
53
	indexOf: function(value){
54
		var list = this;
55
		if (list.length === 0) {
56
			return -1;
57
		}
58
		for (var a = 0, al = list.length;a<al;a++){
59
			if (list[a] == value){
60
				return a;
61
			}
62
		}
63
		return -1;
64
	},
65 View Code Duplication
	lastIndexOf: function(value){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
66
		var list = this;
67
		if (list.length === 0) {
68
			return -1;
69
		}
70
		for (var a = list.length-1;a>=0;a--){
71
			if (list[a] == value){
72
				return a;
73
			}
74
		}
75
		return -1;
76
	},
77 View Code Duplication
	isEqual: function(list2){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
78
		var list = this;
79
		if (list == null || list2 == null) {
2 ignored issues
show
Best Practice introduced by
Comparing list2 to null using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing list to null using the == operator is not safe. Consider using === instead.
Loading history...
80
			return list == list2;
81
		}	
82
		if(list.length != list2.length){
83
			return false;
84
		}
85
		
86
		var len = list.length;
87
		
88
		for (var i = 0;i<len;i++){
89
			if(list[i] !== list2[i]){
90
				return false;
91
			}
92
		}
93
		
94
		return true;
95
	},
96
	isNotEqual: function(list2){
97
		var list = this;
98
		return !IsEqual(list, list2);
99
	},
100
101
	exists: function(){
102
		var list = this;
103
		return list != null && list.length > 0;
1 ignored issue
show
Best Practice introduced by
Comparing list to null using the != operator is not safe. Consider using !== instead.
Loading history...
104
	},
105
	isFirst: function(value){
106
		var list = this;
107
		return list != null && list[0] == value;
1 ignored issue
show
Best Practice introduced by
Comparing list to null using the != operator is not safe. Consider using !== instead.
Loading history...
108
	},
109
	isLast: function(value){
110
		var list = this;
111
		return list != null && list[list.length - 1] == value;
1 ignored issue
show
Best Practice introduced by
Comparing list to null using the != operator is not safe. Consider using !== instead.
Loading history...
112
	},
113 View Code Duplication
	count: function(value, not = false){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
114
		var list = this;
115
		var total = 0;
116
		for (var a = 0, al = list.length;a<al;a++){
117
			if (not) {
118
				if (list[a] != value) {
119
					total++;
120
				}
121
			}else {
122
				if (list[a] == value) {
123
					total++;
124
				}
125
			}
126
		}
127
		return total;
128
	},
129
	or: function(list2){
130
		var list = this;
131
		if (Exists(list)) {
132
			return list;
133
		}
134
		return list2;
135
	},
136
	
137
	part: function(start, end){
138
		var list = this;
139
		
140
		// quickly exit if no items or no results possible
141
		if (list == null || list.length === 0 || start > end || start >= list.length) {
1 ignored issue
show
Best Practice introduced by
Comparing list to null using the == operator is not safe. Consider using === instead.
Loading history...
142
			return [];
143
		}
144
		
145
		// just get the part we need
146
		return list.slice(start, end + 1);
147
	},
148
	
149
	swap: function(slot1, slot2){
150
		var list = this;
151
		var temp = list[slot2];
152
		list[slot2] = list[slot1];
153
		list[slot1] = temp;
154
	},
155
156
	add: function(item){
157
		var list = this;
158
		list.push(item);
159
		return list.length - 1;
160
	},
161
	addToStart: function(item){
162
		var list = this;
163
		list.unshift(item);
164
		return 0;
165
	},
166
	/** return false if item exists, true if item does not */
167
	addOnce: function(value){
168
		var list = this;
169
		
170
		// return false if item exists
171
		if (list.indexOf(value) > -1) {
172
			return false;
173
		}
174
		
175
		// add if not found
176
		list.push(value);
177
		return true;
178
	},
179
	
180
	addArray: function(toAdd, addAtSlot = -1, modifyMain = true){
181
		var list = this;
182
		
183
		if (toAdd != null && toAdd.length > 0) {
1 ignored issue
show
Best Practice introduced by
Comparing toAdd to null using the != operator is not safe. Consider using !== instead.
Loading history...
184
			if (!modifyMain) {
185
				list = list.concat(); /// shallow clone
186
			}
187
			
188
			// set length first so allocates memory (maybe?)
189
			var origLen = list.length;
190
			if (addAtSlot === -1){
191
				list.length += toAdd.length;
192
			}
193
			
194
			// set all slots
195
			var next = addAtSlot === -1 ? origLen : addAtSlot;
196
			for (var a = 0, al = toAdd.length;a<al;a++, next++){
197
				list[next] = toAdd[a];
198
			}
199
		}
200
		return list;
201
	},
202
	
203
	/** adds the given value many times */
204
	addManyTimes: function(val, times){
205
		var list = this;
206
		
207
		if (times <= 0) {
208
			return list;
209
		}
210
		
211
		var n = list.length;
212
		for (var t = 0;t<times;t++){
213
			list[n++] = val;
214
		}
215
		
216
		return list;
217
	},
218
	
219
	addRange: function(toAdd, startSlot, endSlot){
220
		var list = this;
221
		
222
		// exit if no work
223
		if (endSlot < startSlot) {
224
			return;
225
		}
226
		
227
		// per wanted slot of the `add` array
228
		startSlot = startSlot.limitToArray(toAdd);
229
		endSlot = endSlot.limitToArray(toAdd);
230
		for (var s = startSlot;s <= endSlot;s++){
231
			
232
			// add into `main` array
233
			list.push(toAdd[s]);
234
			
235
		}
236
	},
237
	
238
	/** returns final index of added item, or index of already existing item */
239
	findOrAdd: function(value){
240
		var list = this;
241
		
242
		// return index of item if exists
243
		var i = list.indexOf(value);
244
		if (i > -1) {
245
			return i;
246
		}
247
		
248
		// add if not found
249
		i = list.length;
250
		list[i] = value;
251
		return i;
252
	},
253
	
254
	insertOne: function(item, slot){
255
		var list = this;
256
		
257
		// adds one slot at the given point
258
		// modifies the main array
259
		
260
		list.splice(slot, 0, item);
261
	},
262
263
	/** if slot = -1 or outside the array, the item is added to the END of the array.
264
	 * Otherwise the item is added at the given slot. */
265
	insertOneOrAdd: function(item, slot){
266
		var list = this;
267
		
268
		// adds one slot at the given point
269
		// modifies the main array
270
		
271
		if (slot < 0 || slot >= list.length) {
272
			list.push(item);
273
			return list.length - 1;
274
		}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
275
			list.splice(slot, 0, item);
276
			return slot;
277
		}
278
	},
279
	insertArray: function(newItems, slot, returnNew = true){
280
		var list = this;
281
		
282
		// adds many slots at the given point
283
		// returns a new array
284
		if(returnNew){
285
			return list.slice(0, slot).concat(newItems).concat(list.slice(slot));
286
		}
287
		
288
		// adds many slots at the given point
289
		// modifies the main array
290
		for (var a = 0, al = newItems.length;a<al;a++){
291
			list.splice(slot++, 0, newItems[a]);
292
		}
293
		return list;
294
	},
295
	insertArrayAfter: function(newItems, after){
296
		var list = this;
297
		if (list.isLast(after)) {
298
			list.addArray(newItems);
299
		} else {
300
			var i = list.indexOf(after);
301
			list.insertArray(i + 1, newItems);
302
		}
303
	},
304
	
305
306
	removeAndInsert: function(from, to){
307
		var list = this;
308
		
309
		// ensure slots within array
310
		var al = list.length;
311
		from = from.limitTo(0, al - 1);
312
		to = to.limitTo(0, al - 1);
313
		if (to < from) {
314
			var i1 = to;
315
			var i2 = from;
316
		}else {
317
			var i1 = from;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i1 already seems to be declared on line 314. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
318
			var i2 = to;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i2 already seems to be declared on line 315. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
319
		}
320
		
321
		// fill unaffected header
322
		var result = [];
323
		if(i1 > 0){
324
			for (var a = 0;a<i1;a++){
325
				result[a] = list[a];
326
			}
327
		}
328
		
329
		// fill "to"
330
		result[to] = list[from];
331
		
332
		// fill between from and to
333
		if(to < from){
334
			for (a = to + 1; a <= from; a++) {
335
				result[a] = list[a - 1];
336
			}
337
		}else {
338
			for (a = from; a < to; a++) {
339
				result[a] = list[a + 1];
340
			}
341
		}
342
		
343
		// fill unaffected footer
344
		for (var a = i2 + 1;a<al;a++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable a already seems to be declared on line 324. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
345
			result[a] = list[a];
346
		}
347
		
348
		return result;
349
	},
350
	
351
	/** replace a range of items with a given array */
352
	replaceRange: function(replaceStartSlot, replaceEndSlot, newItems, returnNew = true){
353
		var list = this;
354
		
355
		
356
		// simply remove a single item
357
		if (replaceStartSlot == replaceEndSlot && newItems.length === 0) {
358
			if (returnNew) {
359
				list = list.concat();
360
			}
361
			list.splice(replaceStartSlot, 1);
362
			return list;
363
			
364
		// simply replace a single item
365
		}else if (replaceStartSlot == replaceEndSlot && newItems.length === 1) {
366
			if (returnNew) {
367
				list = list.concat();
368
			}
369
			list[replaceStartSlot] = newItems[0];
370
			return list;
371
			
372
		}else{
373
			
374
			// alt method if returning a new array
375
			if(returnNew){
376
				return list.slice(0, replaceStartSlot).concat(newItems).concat(list.slice(replaceEndSlot + 1));
377
			}
378
			
379
			// remove many
380
			list.splice(replaceStartSlot, (replaceEndSlot - replaceStartSlot) + 1);
381
			
382
			// insert many
383
			var slot = replaceStartSlot;
384
			for (var a = 0, al = newItems.length;a<al;a++){
385
				list.splice(slot++, 0, newItems[a]);
386
			}
387
		}
388
		return list;
389
	},
390
	
391
	replace: function(find, replace, stringReplace = false){
392
		var list = this;
393
		for (var i = 0, il = list.length;i<il;i++){
394
			if (stringReplace){
395
396
				// replace substring within string items
397
				var str = list[i];
398
				if (str && str.constructor === String) {
399
					list[i] = str.replaceAll(find, replace);
400
				}
401
			}else{
402
403
				// replace entire items
404
				if (list[i] == find) {
405
					list[i] = replace;
406
				}
407
			}
408
		}
409
	},
410
	replaceOnce: function(find, replace){
411
		var list = this;
412
		for (var i = 0, il = list.length;i<il;i++){
413
			if (list[i] == find) {
414
				list[i] = replace;
415
				return;
416
			}
417
		}
418
	},
419
	replaceMany: function(findArray, replaceArray){
420
		var list = this;
421
		if (findArray.length != replaceArray.length){
422
			return;
423
		}
424
		for (var i = 0, il = list.length;i<il;i++){
425
			for (var f = 0, fl = findArray.length;f<fl;f++){
426
				var find = findArray[f];
427
				if (list[i] == find) {
428
					list[i] = replaceArray[f];
429
					break;
430
				}
431
			}
432
		}
433
	},
434
	
435
	
436
	remove: function(value, stringReplace = false){
437
		var list = this;
438
		for (var i = 0, il = list.length;i<il;i++){
439
			if (stringReplace){
440
441
				// remove substring within string items
442
				var str = list[i];
443
				if (str && str.constructor === String) {
444
					list[i] = str.removeAll(value);
445
				}
446
			}else{
447
448
				// remove entire items
449
				if (list[i] == value) {
450
					list.splice(i, 1);
451
					i--;
1 ignored issue
show
Complexity Coding Style introduced by
You seem to be assigning a new value to the loop variable i here. Please check if this was indeed your intention. Even if it was, consider using another kind of loop instead.
Loading history...
452
					il--;
453
				}
454
			}
455
		}
456
	},
457
	removeOnce: function(val){
458
		var list = this;
459
		var i = list.indexOf(val);
460
		if (i > -1) {
461
			list.splice(i, 1);
462
		}
463
		return i;
464
	},
465
	removeFirst: function(returnNew = false){
466
		var list = this;
467
		if (returnNew) {
468
			return list.slice(1);
469
		}else{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
470
			if (list.length > 0) {
471
				list.splice(0, 1);
472
			}
473
			return list;
474
		}
475
	},
476
	removeFirstX: function(count, returnNew = false){
477
		var list = this;
478
		
479
		// if fewer items than wanted, clear entire array
480
		if (list.length < count) {
481
			if (returnNew) {
482
				return [];
483
			}
484
			list.length = 0;
485
			return list;
486
		}
487
		
488
		// delete X items from start
489
		if (returnNew) {
490
			return list.slice(count);
491
		}else{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
492
			list.splice(0, count);
493
			return list;
494
		}
495
	},
496
	removeLast: function(returnNew = false){
497
		var list = this;
498
		if (returnNew) {
499
			return list.slice(0, list.length - 1);
500
		}
501
		if (list.length > 0) {
502
			list.splice( - 1, 1);
503
		}
504
		return list;
505
	},
506
	removeLastX: function(count, returnNew = false){
507
		var list = this;
508
		
509
		// if fewer items than wanted, clear entire array
510
		if (list.length < count) {
511
			if (returnNew) {
512
				return [];
513
			}
514
			list.length = 0;
515
			return list;
516
		}
517
		
518
		// delete X items from end
519
		if (returnNew) {
520
			return list.slice(0, list.length - count);
521
		}else{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
522
			list.splice( -count, count);
523
			return list;
524
		}
525
	},
526
	
527
	removeEdges: function(fromLeftEdge, fromRightEdge){
528
		var list = this;
529
		if ((list.length - fromLeftEdge - fromRightEdge) <= 0) {
530
			return [];
531
		}
532
		return list.slice(fromLeftEdge, list.length - fromRightEdge);
533
	},
534
	
535
	
536
	splitAt: function(slot, includeSlot = false, includeInFirst = false){
537
		var list = this;
538
		if (includeSlot) {
539
			if (includeInFirst) {
540
				return [list.slice(0, slot + 1), list.slice(slot + 1)];
541
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
542
				return [list.slice(0, slot), list.slice(slot)];
543
			}
544
		}
545
		return [list.slice(0, slot), list.slice(slot+1)];
546
	},
547
	splitAtEvery: function(val){
548
		var list = this;
549
		var splits = [];
550
		var lastSlot = 0;
551
		for (var a = 0, al = list.length;a<al;a++){
552
			if (list[a] == val && a > lastSlot) {
553
				splits.push(list.slice(lastSlot, a));
554
				lastSlot = a + 1;
555
			}
556
		}
557
		return splits;
558
	},
559
	
560
	moveToTop: function(slot, returnNew = false){
561
		var list = this;
562
563
		if (returnNew){
564
565
			// ALWAYS RETURNS NEW ARRAY
566
			
567
			// exit quickly if slot not in array
568
			var al = list.length;
569
			if (slot < 0 || slot >= al) {
570
				return list.concat();
571
			}
572
			
573
			// create new array with slot on top
574
			var newArr = [list[slot]];
575
			var n = 1;
576
			
577
			// add all other slots
578
			for (var a = 0;a<al;a++){
579
				if (a != slot) {
580
					newArr[n++] = list[a];
581
				}
582
			}
583
584
			return newArr;
585
586
		}else{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
587
588
			// MODIFIES ARRAY IN PLACE
589
			
590
			// exit quickly if slot not in array
591
			var al = list.length;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable al already seems to be declared on line 568. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
592
			if (slot < 0 || slot >= al) {
593
				return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
594
			}
595
			
596
			// delete and re-add slot
597
			var val = list[slot];
598
			list.splice(slot, 1);
599
			list.unshift(val);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
600
		}
601
	},
602
	moveToBottom: function(slot, returnNew = false){
603
		var list = this;
604
605
		if (returnNew){
606
607
			// ALWAYS RETURNS NEW ARRAY
608
			
609
			// exit quickly if slot not in array
610
			var al = list.length;
611
			if (slot < 0 || slot >= al) {
612
				return list.concat();
613
			}
614
			
615
			// create new array with slot on top
616
			var newArr = [];
617
			var n = 0;
618
			
619
			// add all other slots
620
			for (var a = 0;a<al;a++){
621
				if (a != slot) {
622
					newArr[n++] = list[a];
623
				}
624
			}
625
			
626
			// add slot to bottom
627
			newArr[n++] = list[slot];
0 ignored issues
show
Unused Code introduced by
The assignment to variable n seems to be never used. Consider removing it.
Loading history...
628
			return newArr;
629
630
		}else{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
631
632
			// MODIFIES ARRAY IN PLACE
633
			
634
			// exit quickly if slot not in array
635
			var al = list.length;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable al already seems to be declared on line 610. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
636
			if (slot < 0 || slot >= al) {
637
				return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
638
			}
639
			
640
			// delete and re-add slot
641
			var val = list[slot];
642
			list.splice(slot, 1);
643
			list.push(val);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
644
		}
645
	},
646
	moveUp: function(item){
647
		var list = this;
648
		
649
		// MODIFIES ARRAY IN PLACE
650
		
651
		// exit quickly if slot not in array, or already on top
652
		var slot = list.indexOf(item);
653
		if (slot <= 0) {
654
			return false;
655
		}
656
		
657
		// move one up
658
		Swap(list, slot, slot - 1);
659
		return true;
660
	},
661
	moveDown: function(item){
662
		var list = this;
663
		
664
		// MODIFIES ARRAY IN PLACE
665
		
666
		// exit quickly if slot not in array, or already at bottom
667
		var al = list.length;
668
		var slot = list.indexOf(item);
669
		if (slot < 0 || slot >= (al - 1)) {
670
			return false;
671
		}
672
		
673
		// move one down
674
		Swap(list, slot, slot + 1);
675
		return true;
676
	},
677
	moveSlotUp: function(slot){
678
		var list = this;
679
		
680
		// MODIFIES ARRAY IN PLACE
681
		
682
		// exit quickly if slot not in array, or already on top
683
		var al = list.length;
684
		if (slot <= 0 || slot >= al) {
685
			return false;
686
		}
687
		
688
		// move one up
689
		Swap(list, slot, slot - 1);
690
		return true;
691
	},
692
	moveSlotDown: function(slot){
693
		var list = this;
694
		
695
		// MODIFIES ARRAY IN PLACE
696
		
697
		// exit quickly if slot not in array, or already at bottom
698
		var al = list.length;
699
		if (slot < 0 || slot >= (al - 1)) {
700
			return false;
701
		}
702
		
703
		// move one down
704
		Swap(list, slot, slot + 1);
705
		return true;
706
	},
707
	/** Move an item from the given list, to the start/end of the target list */
708
	moveToArray: function(item, toList, evenIfExists = false, addToEnd = true){
709
		var list = this;
710
		
711
		// remove from source list
712
		RemoveOne(list, item);
713
		
714
		// add to target list
715
		if (evenIfExists || toList.indexOf(item) === -1) {
716
			if (addToEnd) {
717
				toList.push(item);
718
			}else{
719
				toList.unshift(item);
720
			}
721
			return true;
722
		}
723
		
724
		return false;
725
	},
726
727
	
728
	contains: function(value){
729
		var list = this;
730
		if (list.length === 1) {
731
			return list[0] == value;
732
		}
733
		return list.indexOf(value) > -1;
734
	},
735
	containsAny: function(values){
736
		var list = this;
737
		return IndexOfAny(list, values) > -1;
738
	},
739
	containsAll: function(values){
740
		var list = this;
741
		
742
		// exit if either null
743
		if (list == null || values == null || list.length === 0 || values.length === 0) {
2 ignored issues
show
Best Practice introduced by
Comparing values to null using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing list to null using the == operator is not safe. Consider using === instead.
Loading history...
744
			return false;
745
		}
746
		
747
		// check if all found
748
		for (var f = 0, fl = values.length;f<fl;f++){
749
			if (list.indexOf(values[f]) === -1) {
750
				return false;
751
			}
752
		}
753
		return true;
754
	},
755
	
756
757
	indexOfArray: function(containsArr){
758
		var list = this;
759
		
760
		// returns index of containing list in main array
761
		
762
		if (list.length < containsArr.length) {
763
			return -1;
764
		}
765
		
766
		var cl = containsArr.length;
767
		for (var a = 0, al = list.length - (cl - 1);a<al;a++){
768
			
769
			var allMatch = true;
770
			for (var c = 0;c<cl;c++){
771
				if (list[a+c] != containsArr[c]) {
772
					allMatch = false;
773
					break;
774
				}
775
			}
776
			
777
			if (allMatch) {
778
				return a;
779
			}
780
		}
781
		return -1;
782
	},
783
	
784
785
	beginsWithArray: function(value){
786
		return this.startsWithArray(value);
787
	},
788
	startsWithArray: function(check){
789
		var list = this;
790
		
791
		// quickly test if length sufficient
792
		var clen = check.length;
793
		var mlen = list.length;
794
		if (mlen < clen) {
795
			return false;
796
		}
797
		
798
		// check if first slots match
799
		for (var b = 0;b<clen;b++){
800
			if (list[b] != check[b]) {
801
				return false;
802
			}
803
		}
804
		return true;
805
	},
806 View Code Duplication
	endsWithArray: function(check){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
807
		var list = this;
808
		
809
		// quickly test if length sufficient
810
		var clen = check.length;
811
		var mlen = list.length;
812
		if (mlen < clen) {
813
			return false;
814
		}
815
		
816
		// check if last slots match
817
		var off = (mlen - clen);
818
		for (var b = 0;b<clen;b++){
819
			if (list[off + b] != check[b]) {
820
				return false;
821
			}
822
		}
823
		return true;
824
	},
825
	beginsWith: function(value){
826
		return this.startsWith(value);
827
	},
828
	startsWith: function(value){
829
		var list = this;
830
		return list[0] == value;
831
	},
832
	endsWith: function(value){
833
		var list = this;
834
		return list[list.length - 1] == value;
835
	},
836
	
837 View Code Duplication
	next: function(obj, wrap = false){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
838
		var list = this;
839
		if (list == null) {
1 ignored issue
show
Best Practice introduced by
Comparing list to null using the == operator is not safe. Consider using === instead.
Loading history...
840
			return null;
841
		}
842
		var i = list.indexOf(obj);
843
		if (i > -1) {
844
			return (wrap && i >= (list.length - 1)) ? list[0] : list[i + 1];
845
		}
846
		return null;
847
	},
848
	prev: function(obj, wrap = false){
849
		var list = this;
850
		if (list == null) {
1 ignored issue
show
Best Practice introduced by
Comparing list to null using the == operator is not safe. Consider using === instead.
Loading history...
851
			return null;
852
		}
853
		var i = list.indexOf(obj);
854
		if (i > 0) {
855
			return wrap ? list[list.length - 1] : list[i - 1];
856
		}
857
		return null;
858
	},
859
	
860
	
861
	/** Returns the nearest existing slot value in the array. Returns `ifNoSlots` if the array is empty. */
862
	within: function(slot, ifNoSlots = null){
863
		var list = this;
864
		
865
		// return null if array empty
866
		var len = list.length;
867
		if (len === 0) {
868
			return ifNoSlots;
869
		}
870
		
871
		// return first slot if index negative
872
		if (slot < 0) {
873
			return list[0];
874
		}
875
		
876
		// return last slot if index more than last slot
877
		if (slot >= len) {
878
			return list[len - 1];
879
		}
880
		
881
		// return given slot if within array
882
		return list[slot];
883
	},
884
	
885
	first: function(list){
886
		var list = this;
887
		var len = list.length;
888
		if (len === 0) {
889
			return null;
890
		}
891
		return list[0];
892
	},
893
	firstExisting: function(slots, blankVal = null){
894
		var list = this;
895
		for (var s = 0, sl = slots.length;s<sl;s++){
896
			var val;
897
			if ((val = list[slots[s]]) != blankVal) {
898
				return val;
899
			}
900
		}
901
		return null;
902
	},
903
	last: function(list){
904
		var list = this;
905
		var len = list.length;
906
		if (len === 0) {
907
			return null;
908
		}
909
		return list[len-1];
910
	},
911
	lastX: function(count){
912
		var list = this;
913
		var s = (0).max(list.length - count);
914
		return list.slice(s, list.length);
915
	},
916
	setFirst: function(value){
917
		var list = this;
918
		var len = list.length;
919
		if (len === 0) {
920
			return;
921
		}
922
		list[0] = value;
923
	},
924
	setLast: function(value){
925
		var list = this;
926
		var len = list.length;
927
		if (len === 0) {
928
			return;
929
		}
930
		list[len-1] = value;
931
	},
932
	
933
	random: function(list){
934
		var list = this;
935
		
936
		// return null if array empty
937
		if (list.length === 0) {
938
			return null;
939
		}
940
		
941
		// return random slot within array
942
		return list[parseInt(Math.random() * 1000000) % list.length];
943
	},
944
945
	pick: function(IDs, sameSlots = false, fastAndUnsafe = false, out = null, evenIfNull = false){
946
		var list = this;
947
		if (out == null){
1 ignored issue
show
Best Practice introduced by
Comparing out to null using the == operator is not safe. Consider using === instead.
Loading history...
948
			out = [];
949
		}
950
		
951
		if (IDs){
952
			if (fastAndUnsafe) {
953
				
954
				for (var i = 0, il = IDs.length;i<il;i++){
955
					var id = IDs[i];
956
					var val = list[id];
957
					if (sameSlots) {
958
						out[id] = val;
959
					}else{
960
						out.push(val);
961
					}
962
				}
963
				
964
			}else{
965
				
966
				for (var i = 0, il = IDs.length;i<il;i++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 954. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable il already seems to be declared on line 954. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
967
					id = IDs[i];
968
					if (id > -1){
969
						val = list[id];
970
						if (val != null || evenIfNull) {
1 ignored issue
show
Best Practice introduced by
Comparing val to null using the != operator is not safe. Consider using !== instead.
Loading history...
971
							if (sameSlots) {
972
								out[id] = val;
973
							}else{
974
								out.push(val);
975
							}
976
						}
977
					}
978
				}
979
				
980
			}
981
		}
982
		
983
		return out;
984
	},
985
986
	/** Get the data of `list`, by searching `indexID` in `indexArr`, or return `defaultVal` if not found */
987
	getByMatchingArray: function(indexArr, indexID, defaultVal = null){
988
		var list = this;
989
		var slot = indexArr.indexOf(indexID);
990
		return slot === -1 ? defaultVal : list[slot];
991
	},
992
	/** Set the data of `list`, by searching `indexID` in `indexArr` */
993
	setByMatchingArray: function(indexArr, indexID, data){
994
		var list = this;
995
		var slot = indexArr.indexOf(indexID);
996
		if (slot === -1) {
997
			return false;
998
		}
999
		list[slot] = data;
1000
		return true;
1001
	},
1002
	
1003
	page: function(page, pageLength, invisibleRows = null){
1004
		var list = this;
1005
		
1006
		// ensure page no. in limits
1007
		var lastPage = Math.ceil(list.length / pageLength);
1008
		page = page.limitTo(0, lastPage - 1);
1009
		
1010
		// get first/last row in page
1011
		var pageStart = page*pageLength;/// 0-based - first row in page
1012
		var pageEnd = (pageStart + pageLength) - 1;/// 0-based - last row in page
1013
		
1014
		// get on-page rows
1015
		var visibleRows = list.getRange(pageStart, pageLength);
1016
		
1017
		// get off-page rows
1018
		if (invisibleRows) {
1019
			invisibleRows.addRange(list, 0, pageStart - 1);
1020
			invisibleRows.addRange(list, pageEnd + 1, list.length - 1);
1021
		}
1022
		
1023
		return visibleRows;
1024
	},
1025
	
1026
	trim: function(returnNew = false, trimVal = null){
1027
		var list = this;
1028
		var first = IndexOf(list, trimVal, true);
1029
		if (first === -1) {
1030
			if (returnNew) {
1031
				return [];
1032
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1033
				list.length = 0;
1034
			}
1035
		}else{
1036
			var last = list.lastIndexOf(trimVal, true);
1037
			if (returnNew) {
1038
				return GetManySE(list, first, last);
1039
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1040
				
1041
				if (first != -1 && first != 0){
1 ignored issue
show
Best Practice introduced by
Comparing first to 0 using the != operator is not safe. Consider using !== instead.
Loading history...
1042
					DeleteManySE(list, 0, first-1);
1043
				}
1044
				if (last != -1){
1045
					list.length = last - first + 1; 
1046
				}
1047
			}
1048
		}
1049
		return list;
1050
	},
1051
1052
	trimLeft: function(returnNew = false, trimVal = null){
1053
		var list = this;
1054
		var first = IndexOf(list, trimVal, true);
1055
		if (first === -1) {
1056
			if (returnNew) {
1057
				return [];
1058
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1059
				list.length = 0;
1060
			}
1061
		}else{
1062
			if (returnNew) {
1063
				return GetAfter(list, first);
1064
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1065
				if (first != -1 && first != 0){
1 ignored issue
show
Best Practice introduced by
Comparing first to 0 using the != operator is not safe. Consider using !== instead.
Loading history...
1066
					DeleteManySE(list, 0, first-1);
1067
				}
1068
			}
1069
		}
1070
		return list;
1071
	},
1072
	trimRight: function(returnNew = false, trimVal = null){
1073
		var list = this;
1074
		var last = IndexOf(list, trimVal, true);
1075
		if (last === -1) {
1076
			if (returnNew) {
1077
				return [];
1078
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1079
				list.length = 0;
1080
			}
1081
		}else{
1082
			if (returnNew) {
1083
				return GetBefore(list, last);
1084
			}else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1085
				list.length = last + 1;
1086
			}
1087
		}
1088
		return list;
1089
	},
1090
	
1091
	transpose: function() {
1092
		var arr = this;
1093
		var transposed = [];
1094
		
1095
		for (var r = 0; r < arr.length; r++) {
1096
			for (var c = 0; c < arr[r].length; c++) {
1097
				if (transposed[c] == null) {
1 ignored issue
show
Best Practice introduced by
Comparing transposed.c to null using the == operator is not safe. Consider using === instead.
Loading history...
1098
					transposed[c] = [];
1099
				}
1100
				transposed[c][r] = arr[r][c];
1101
			}
1102
		}
1103
		
1104
		return transposed;
1105
	},
1106
	
1107
	none:null
1108
};
1109
1110
// register funcs
1111
UB.registerFuncs(Array.prototype, arrayFuncs);
1112